package service;

import java.net.URL;
import java.util.Hashtable;
import java.util.LinkedList;

import org.dom4j.Document;

import bpel.BPELProcess;
import bpel.parser.BPELParser;

/**
 * 
 * @author Maurice & Topia
 * 
 */
public class BusESB {

	private static BusESB singleton = null;
	private LinkedList<Integer> usedTokens;
	private Hashtable<String, BPELProcess> businessProcesses = null;
	private Hashtable<Integer, Document> availableResults = null;

	public static BusESB getInstance() {
		if (null == singleton) {
			singleton = new BusESB();
		}

		return singleton;
	}

	private BusESB() {
		this.businessProcesses = new Hashtable<String, BPELProcess>();
		this.availableResults = new Hashtable<Integer, Document>();
		this.usedTokens = new LinkedList<Integer>();
	}

	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}

	protected void addBusinessProcess(URL s) throws Exception {
		BPELParser parser = new BPELParser();
		BPELProcess process = parser.parse(s.toURI().toString());

		System.out.println("Adding service : " + s);

		this.businessProcesses.put(process.getName(), process);
	}

	protected boolean removeBusinessProcess(String id) {
		if (this.businessProcesses.containsKey(id)) {
			this.businessProcesses.remove(id);
			return true;
		} else {
			System.err.println("(BusESB) Can't remove business process " + id + " because it doesn't exists");
			return false;
		}
	}

	public BPELProcess getBusinessProcess(String s) {
		return businessProcesses.get(s);
	}

	public int getFreeToken() {
		for (int i = 0; i < Integer.MAX_VALUE; i++) {
			if (!usedTokens.contains((Integer) i)) {
				return i;
			}
		}

		// Should never happen
		System.err.println("(BusESB) All tokens are used !");
		return -1;
	}

	public synchronized void addResultat(int token, Document output) {
		if (output != null) {
			this.availableResults.put(token, output);
		}
	}

	public synchronized Document getResultat(int token) {
		if (this.availableResults.containsKey(token)) {
			usedTokens.remove((Integer) token);
			return this.availableResults.get(token);
		}
		return null;
	}
}
